home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dirut
/
dosdir21.zip
/
FNSPLIT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-22
|
7KB
|
305 lines
/*
* C/C++ Run Time Library - Version 5.0
*
* Copyright (c) 1987, 1992 by Borland International
* All Rights Reserved.
*
* Modification History:
* 10-Jun-92 Borland Original version.
* 17-May-94 J Mathews Modified for Unix.
* 8-Jun-94 J Mathews Added VMS handling,
* Added path expansion for ~ symbol on UNIX.
*/
#include <string.h>
#include "dosdir.h"
#ifdef UNIX
# include <pwd.h>
# define DD_MAXUSERNAME 100
#endif
static void CopyIt OF((char *dst, const char *src, unsigned maxlen));
/*---------------------------------------------------------------------*
Name CopyIt - copies a string to another
Prototype in local to this module
*---------------------------------------------------------------------*/
static void CopyIt(dst, src, maxlen)
char *dst;
const char *src;
unsigned maxlen;
{
if (dst) {
if (strlen(src) >= maxlen)
{
strncpy(dst, src, maxlen);
dst[maxlen] = 0;
}
else
strcpy(dst, src);
}
}
#ifndef VMS
static int DotFound OF((char *pB));
/*---------------------------------------------------------------------*
Name DotFound - checks for special directory names
Prototype in local to this module
*---------------------------------------------------------------------*/
static int DotFound(pB)
char *pB;
{
if (*(pB-1) == '.') pB--;
switch (*--pB) {
#ifdef MSDOS
case ':' :
if (*(pB-2) != '\0')
break;
case '\\' :
#endif
case '/' :
case '\0' :
return 1;
}
return 0;
}
#endif /* ?!VMS */
/*---------------------------------------------------------------------*
Name dd_fnsplit - splits a full path name into its components
Usage #include <dosdir.h>
int dd_fnsplit(const char *path, char * drive, char * dir,
char * name, char * ext);
Prototype in dosdir.h
Description dd_fnsplit takes a file's full path name (path) as a string
in the form
/DIR/SUBDIR/FILENAME (UNIX)
X:\DIR\SUBDIR\NAME.EXT (MS-DOS)
NODE::DEVICE:[PATH]NAME.EXT;VERSION (VMS)
and splits path into its four components. It then stores
those components in the strings pointed to by dir and
ext. (Each component is required but can be a NULL,
which means the corresponding component will be parsed
but not stored.)
The maximum sizes for these strings are given by the
constants MAXDRIVE, MAXDIR, MAXPATH, MAXNAME and MAXEXT,
(defined in dosdir.h) and each size includes space for
the null-terminator.
Constant String
DD_MAXPATH path
DD_MAXDRIVE drive; includes colon; not used by UNIX
DD_MAXDIR dir; includes leading and trailing
backslashes for DOS or slashes for UNIX
DD_MAXFILE filename
DD_MAXEXT ext; includes leading dot (.)
(not used by UNIX)
dd_fnsplit assumes that there is enough space to store each
non-NULL component. fnmerge assumes that there is enough
space for the constructed path name. The maximum constructed
length is DD_MAXPATH.
When dd_fnsplit splits path, it treats the punctuation as
follows:
* drive keeps the colon attached (C:, A:, etc.).
It is not applicable to unix file system.
* dir keeps the leading and trailing slashes
(/usr/local/bin/, /src/, etc.)
* ext keeps the dot preceding the extension (.c, .doc, etc.)
It is not applicable to unix file system.
Return value dd_fnsplit returns an integer (composed of five flags,
defined in dosdir.h) indicating which of the full path name
components were present in path; these flags and the components
they represent are:
EXTENSION an extension
FILENAME a filename
DIRECTORY a directory (and possibly
sub-directories)
DRIVE a drive specification (see dir.h)
WILDCARDS wildcards (* or ? cards)
*---------------------------------------------------------------------*/
int dd_fnsplit(pathP, driveP, dirP, nameP, extP)
const char *pathP;
char *driveP, *dirP, *nameP, *extP;
{
register char *pB;
register int Wrk;
int Ret;
char buf[ DD_MAXPATH+2 ];
/*
* Set all string to default value zero
*/
Ret = 0;
if (driveP) *driveP = 0;
if (dirP) *dirP = 0;
if (nameP) *nameP = 0;
if (extP) *extP = 0;
/*
* Copy filename into template up to DD_MAXPATH characters
*/
pB = buf;
while (*pathP == ' ') pathP++;
if ((Wrk = strlen(pathP)) > DD_MAXPATH)
Wrk = DD_MAXPATH;
*pB++ = 0;
strncpy(pB, pathP, Wrk);
*(pB += Wrk) = 0;
/*
* Split the filename and fill corresponding nonzero pointers
*/
Wrk = 0;
for (; ; ) {
switch (*--pB) {
case '.':
#ifndef VMS
if (!Wrk && (*(pB+1) == '\0')) Wrk = DotFound(pB);
#endif
#if (defined(MSDOS) || defined(VMS))
if ((!Wrk) && ((Ret & EXTENSION) == 0)) {
Ret |= EXTENSION;
CopyIt(extP, pB, DD_MAXEXT - 1);
*pB = 0;
}
#endif
continue;
#if defined(MSDOS)
case ':' :
if (pB != &buf[2])
continue;
#elif defined(UNIX)
case '~' :
if (pB != &buf[1])
continue;
else {
/* expand path as appropriate */
struct passwd *pw = NULL;
char* tail = strchr (pB, '/');
int len;
if (tail != NULL) {
len = tail - (pB+1);
if (len > 0) {
char username[DD_MAXUSERNAME];
if (len <= DD_MAXUSERNAME)
{
strncpy(username, pB+1, len);
username[len] = 0;
pw = getpwnam(username);
}
}
else
pw = getpwuid (getuid());
if (pw != NULL && (len=strlen(pw->pw_dir)) < DD_MAXDIR)
{
strcpy(dirP, pw->pw_dir);
dirP += len;
}
else
strcpy (dirP++, "?");
CopyIt(dirP, tail, DD_MAXDIR - len - 1);
dirP += strlen(dirP);
}
else {
Wrk = 1;
if (pB[1] != 0)
pw = getpwnam (pB + 1);
else
pw = getpwuid (getuid());
if (pw != NULL && (len=strlen(pw->pw_dir)) < DD_MAXDIR)
{
strcpy(dirP, pw->pw_dir);
dirP += len;
}
else
strcpy (dirP++, "?");
}
*pB-- = 0;
Ret |= DIRECTORY;
}
#endif /* ?MSDOS */
case '\0' :
if (Wrk) {
if (*++pB)
Ret |= DIRECTORY;
CopyIt(dirP, pB, DD_MAXDIR - 1);
#ifdef MSDOS
*pB-- = 0;
#endif
break;
}
#ifdef MSDOS
case '\\' :
#endif
#if (defined(MSDOS) || defined(UNIX))
case '/':
#endif
#ifdef VMS
case ']' :
case ':' :
#endif
if (!Wrk) {
Wrk++;
if (*++pB) Ret |= FILENAME;
CopyIt(nameP, pB, DD_MAXFILE - 1);
*pB-- = 0;
#ifdef MSDOS
if (*pB == 0 || (*pB == ':' && pB == &buf[2]))
#else
if (*pB == 0)
#endif
break;
}
continue;
#ifndef VMS
case '[' :
#endif
case '*' :
#ifdef VMS
case '%' :
#else
case '?' :
#endif
if (!Wrk) Ret |= WILDCARDS;
default :
continue;
}
break;
}
#ifdef MSDOS
if (*pB == ':') {
if (buf[1]) Ret |= DRIVE;
CopyIt(driveP, &buf[1], DD_MAXDRIVE - 1);
}
#endif
return (Ret);
}